<template>
  <div>
    <el-upload
      v-if="type == 'url'"
      ref="upload"
      style="display: none"
      :auto-upload="true"
      name="file"
      :show-file-list="false"
      :limit="1"
      :headers="upload.headers"
      :action="upload.url"
      :data="upload.data"
      :disabled="upload.isUploading"
      :on-change="handleFileChange"
      :before-upload="handleBeforeUpload"
      :on-success="handleUploadSuccess"
      :on-error="handleUploadError"
    />
    <div style="border: 1px solid #ccc">
      <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editor"
        :default-config="toolbarConfig"
        :mode="mode"
      />
      <Editor
        v-model="html"
        :style="{'height': height || '500px', 'overflow-y': 'hidden'}"
        :default-config="editorConfig"
        :mode="mode"
        @onChange="onBlur"
        @onCreated="onCreated"
      />
    </div>
  </div>
</template>

<script>
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { getToken } from '@/utils/auth'
import '@wangeditor/editor/dist/css/style.css'
export default {
  name: 'NewEdit',
  components: { Editor, Toolbar },
  props: {
    /* 编辑器的内容 */
    value: {
      type: String,
      default: ''
    },
    /* 高度 */
    height: {
      type: Number | String,
      default: null
    },
    /* 最小高度 */
    minHeight: {
      type: Number,
      default: null
    },
    /* 只读 */
    readOnly: {
      type: Boolean,
      default: false
    },
    /* 类型（base64格式、url格式） */
    type: {
      type: String,
      default: 'url'
    }
  },
  data() {
    return {
      // 用户导入参数
      upload: {
        title: '', // 弹出层标题
        isUploading: false, // 是否禁用上传
        url: process.env.VUE_APP_BASE_API + 'admin-api/infra/file/upload', // 请求地址
        headers: { Authorization: 'Bearer ' + getToken() }, // 设置上传的请求头部
        data: {} // 上传的额外数据
      },
      // 最大图片尺寸 M
      imageFileSize: 1.5,
      fileType: ['png', 'jpg', 'jpeg'],
      editor: null,
      html: '<p>hello</p>',
      toolbarConfig: {
        excludeKeys: ['uploadVideo']
      },
      editorConfig: { placeholder: '请输入内容...', MENU_CONF: {}},
      mode: 'default', // or 'simple'
      resolve: null,
      reject: null
    }
  },
  watch: {
    value: {
      handler(val) {
        if (val !== this.html) {
          this.html = val === null ? '' : val
        }
      },
      immediate: true
    }
  },
  created() {
    const _this = this
    this.editorConfig.MENU_CONF['uploadImage'] = {
      // 自定义选择图片
      async customBrowseAndUpload(insertFn) {
        // 自己选择文件
        // 自己上传文件，并得到图片 url alt href
        // 最后插入图片
        await _this.handleUploadImg().then(
          (url) => {
            insertFn(url, '图片', url)
          },
          (res) => {
          }
        )
      }
    }
  },
  mounted() {
  },
  beforeDestroy() {
    const editor = this.editor
    if (editor == null) return
    editor.destroy() // 组件销毁时，及时销毁编辑器
  },
  methods: {
    getValue() {
      return this.html
    },
    // 监听富文本变化，自动更新到父组件
    onBlur() {
      const html = this.editor.getHtml()
      this.$emit('input', html)
    },
    // 异步获取图片上传地址
    handleUploadImg() {
      return new Promise((resolve, reject) => {
        this.$refs.upload.$children[0].$refs.input.click()
        this.resolve = resolve
        this.reject = reject
      })
    },
    onCreated(editor) {
      this.editor = Object.seal(editor) // 一定要用 Object.seal() ，否则会报错
    },
    /** 处理上传的文件发生变化 */
    handleFileChange(file, fileList) {
      this.upload.data.path = file.name
    },
    // 上传前校检格式和大小
    handleBeforeUpload(file) {
      if (
        file.type.indexOf('image') === -1 &&
        file.type.indexOf('video') === -1
      ) {
        this.$modal.msgError('请上传图片、视频文件')
        return false
      }
      let isImg = false
      let isVideo = false
      if (this.fileType.length) {
        let fileExtension = ''
        if (file.name.lastIndexOf('.') > -1) {
          fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
        }
        isImg = this.fileType.some((type) => {
          if (file.type.indexOf(type) > -1) return true
          if (fileExtension && fileExtension.indexOf(type) > -1) return true
          return false
        })
      } else {
        isImg = file.type.indexOf('image') > -1
      }
      isVideo = file.type.indexOf('video') > -1
      if (isImg && this.imageFileSize) {
        const isLt = file.size / 1024 / 1024 < this.imageFileSize
        if (!isLt) {
          this.$modal.msgError(
            `上传图片大小不能超过 ${this.imageFileSize} MB!`
          )
          return false
        }
      }
      if (isVideo) {
        // 限制500M
        const isLt = file.size / 1024 / 1024 < 500
        if (!isLt) {
          this.$modal.msgError(`上传视频大小不能超过500MB!`)
          return false
        }
      }
      this.$modal.loading('正在上传，请稍候...')
    },
    /** 文件上传成功处理 */
    handleUploadSuccess(res, file) {
      this.$modal.closeLoading()
      this.$refs.upload.clearFiles()
      // 清理
      this.upload.isUploading = false
      this.resolve(res.data)
    },
    handleUploadError() {
      this.upload.isUploading = false // 禁止修改
      this.$modal.msgError('上传图片失败，请重试')
      this.$modal.closeLoading()
      this.reject(null)
    }
  }
}
</script>

<style>
.editor,
.ql-toolbar {
  white-space: pre-wrap !important;
  line-height: normal !important;
}
.quill-img {
  display: none;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {
  content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
  border-right: 0px;
  content: "保存";
  padding-right: 0px;
}

.ql-snow .ql-tooltip[data-mode="video"]::before {
  content: "请输入视频地址:";
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: "14px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
  content: "10px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
  content: "18px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
  content: "32px";
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: "文本";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: "标题1";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: "标题2";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: "标题3";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: "标题4";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: "标题5";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: "标题6";
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: "标准字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
  content: "衬线字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
  content: "等宽字体";
}
</style>
